// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// Client for secure_socket_renegotiate_test, that runs in a subprocess.
// The test verifies that client certificates work, if the client and server
// are in separate processes, and that connection renegotiation can request
// a client certificate to be sent.

import "dart:async";
import "dart:convert";
import "dart:io";

const HOST_NAME = "localhost";
const CERTIFICATE = "localhost_cert";


class ExpectException implements Exception {
  ExpectException(this.message);
  String toString() => message;
  String message;
}


void expectEquals(expected, actual) {
  if (actual != expected) {
    throw new ExpectException('Expected $expected, found $actual');
  }
}


void expect(condition) {
  if (!condition) {
    throw new ExpectException('');
  }
}


void runClient(int port) {
  SecureSocket.connect(HOST_NAME, port, sendClientCertificate: true)
    .then((SecureSocket socket) {
      X509Certificate certificate = socket.peerCertificate;
      expect(certificate != null);
      expectEquals('CN=localhost', certificate.subject);
      expectEquals('CN=myauthority', certificate.issuer);
      StreamIterator<String> input = new StreamIterator(socket
          .transform(UTF8.decoder)
          .transform(new LineSplitter()));
      socket.writeln('first');
      input.moveNext()
        .then((success) {
          expect(success);
          expectEquals('first reply', input.current);
          socket.renegotiate();
          socket.writeln('renegotiated');
          return input.moveNext();
        })
        .then((success) {
          expect(success);
          expectEquals('server renegotiated', input.current);
          X509Certificate certificate = socket.peerCertificate;
          expect(certificate != null);
          expectEquals("CN=localhost", certificate.subject);
          expectEquals("CN=myauthority", certificate.issuer);
          socket.writeln('second');
          return input.moveNext();
        })
        .then((success) {
          expect(success != true);
          socket.close();
        });
    });
}


void main(List<String> args) {
  SecureSocket.initialize(database: args[1], password: 'dartdart');
  runClient(int.parse(args[0]));
}
